package com.compression.tool.util;

import com.compression.tool.compression.ZipCompression;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.logging.Logger;
import java.util.stream.Stream;

/**
 * @author 自然醒
 * @version 1.0
 */

/**
 * 对文件的基本操作工具
 */
public class FileUtils {
    private static final Logger logger = Logger.getLogger(FileUtils.class.getName());

    /**
     * 计算文件大小
     *
     * @param files
     * @return 文件大小
     */
    public static long calculateFileTotalSize(List<File> files) {
        logger.info("计算文件大小");
        if (files == null || files.isEmpty()) {
            return 0;
        }
        long total = 0;
        for (File file : files) {
            total += calculateFileSize(file.toPath());
        }
        return total;
    }

    /**
     * 计算文件大小NIO框架
     *
     * @param path
     * @return 文件大小
     */
    public static long calculateFileSize(Path path) {
        logger.info("处理目录下的文件大小");
        try {
            if (Files.isRegularFile(path)) {
                return Files.size(path);
            } else if (Files.isDirectory(path)) {
                // 使用try-with-resources确保资源释放
                try (Stream<Path> walk = Files.walk(path)) {
                    // 对于非常大的目录结构，可能消耗较多内存
                    return walk
                            .filter(Files::isRegularFile)// 返回Stream<Path>，需要处理大量文件时可能内存压力较大
                            .mapToLong(p -> {
                                try {
                                    return Files.size(p);
                                } catch (IOException e) {
                                    return 0L;
                                }
                            })
                            .sum();
                }
            }
        } catch (IOException e) {
            System.err.println("无法访问: " + path);
        } catch (SecurityException e) {
            System.err.println("权限不足: " + path);
        }
        return 0L;
    }


    /**
     * 获取文件扩展名(小写)
     *
     * @param file
     * @return 文件扩展名
     */
    public static String getFileExtension(File file) {
        String fileName = file.getName();
        int dotIndex = fileName.lastIndexOf('.'); // 获取扩展名索引
        // 判断扩展名是否合法
        if (dotIndex > 0 && dotIndex < fileName.length() - 1) {
            return fileName.substring(dotIndex + 1).toLowerCase();
        }
        return "";
    }

    /**
     * 验证文件是否为有效的压缩文件格式
     *
     * @param file
     * @return
     */
    public static boolean isValidArchive(File file) {
        if (file == null || !file.exists() || !file.isFile()) {
            return false;
        }
        String fileExtension = getFileExtension(file);
        return fileExtension.equals("zip")
                || fileExtension.equals("rar")
                || fileExtension.equals("7z")
                || fileExtension.equals("tar")
                || fileExtension.equals("gz");
    }

    /**
     * 检测文件类型
     *
     * @param file
     * @return
     */
    public static String detectFile(File file) {
        String fileExtension = getFileExtension(file);
        switch (fileExtension) {
            case "txt":
            case "log":
            case "ini":
            case "conf":
                return "text";
            case "jpg":
            case "jpeg":
            case "png":
            case "gif":
            case "bmp":
                return "image";
            case "pdf":
                return "pdf";
            case "doc":
            case "docx":
                return "word";
            case "xls":
            case "xlsx":
                return "excel";
            case "ppt":
            case "pptx":
                return "powerpoint";
            case "zip":
            case "rar":
            case "7z":
            case "tar":
            case "gz":
            case "bz2":
                return "archive";
            case "mp3":
            case "wav":
            case "flac":
                return "audio";
            case "mp4":
            case "avi":
            case "mkv":
            case "mov":
                return "video";
            default:
                return "unknown";
        }
    }


    /**
     * 格式化文件大小
     *
     * @param size
     * @return
     */
    public static String formatFileSize(long size) {
        if (size < 1024) {
            return size + " B";
        } else if (size < 1024 * 1024) {
            return String.format("%.1f KB", size / 1024.0);
        } else if (size < 1024 * 1024 * 1024) {
            return String.format("%.1f MB", size / (1024.0 * 1024.0));
        } else {
            return String.format("%.1f GB", size / (1024.0 * 1024.0 * 1024.0));
        }
    }



}
